home *** CD-ROM | disk | FTP | other *** search
/ No Fragments Archive 12: Textmags & Docs / nf_archive_12.iso / MAGS / SOURCES / ATARI_SRC.ZIP / atari source / AHDI / SYQUEST / SQHDX / DSMARK.C < prev    next >
Encoding:
C/C++ Source or Header  |  2001-02-09  |  12.1 KB  |  379 lines

  1. /*
  2.  *  Dsmark.c
  3.  *    Routines for performing a destructive markbad.
  4.  */
  5.  
  6. /* 23-Nov-87    ml.    just started.    */
  7.  
  8. #include "obdefs.h"
  9. #include "gemdefs.h"
  10. #include "osbind.h"
  11. #include "defs.h"
  12. #include "part.h"
  13. #include "bsl.h"
  14. #include "hdx.h"
  15. #include "addr.h"
  16.  
  17. extern SECTOR badbuf[];        /* bad sectors buffer */
  18.  
  19. extern long addbsl();
  20. extern int wdesk, hdesk;
  21.  
  22. /*
  23.  *  Destructive Markbad for entire device.
  24.  *    Mechanism:
  25.  *        - write data to entire device, read it back, and compare
  26.  *          if there is any difference. (done in markdev())
  27.  *        - all new bad sectors are added to the bad sector list.
  28.  *          (done in markdev())
  29.  *        - repeat above for the number of passes passed in.
  30.  *    Input:
  31.  *        pdev - physical device number.
  32.  *        hdsiz - size of hard disk in sectors.
  33.  *        pass - number of passes to be performed.
  34.  *        pattern - data pattern to test the disk with.
  35.  *    Output:
  36.  *        bsl - bad sector list with added entries if any. (in bsl.h)
  37.  *    Return:
  38.  *        totbad - total number of bad sectors found.
  39.  *        ERROR - if any of the first 3 sectors is bad, or not enough
  40.  *            memory for buffer.
  41.  */
  42. long
  43. dsmarkbad(pdev, hdsiz, pass, pattern)
  44. int pdev;    /* phys dev num */
  45. long hdsiz;    /* hard disk size */
  46. int pass;    /* num cycles */
  47. long pattern;    /* data pattern to test disk */
  48. {
  49.     char *inbuf;      /* buffer to hold data to be written to the disk */
  50.     char numbuf[10];
  51.     long totbad;      /* total num of bad sectors found */
  52.     long ret;          /* return code from markdev() */
  53.     long markdev();
  54.  
  55.     
  56.     /* Allocate memory for biggest data buffer necessary */
  57.     if ((inbuf = (char *)Malloc((long)(MAXSECTS << 9))) <= 0)
  58.         return err(nomemory);
  59.  
  60.     /* Throw up message box to inform user about 
  61.        the processing of destructive markbad.  */
  62.     totbad = nument(VENDOR);  /* Number of existing VENDOR bad sectors */
  63.     ltoa(totbad, numbuf);
  64.     (dmrkmsg[OLDBAD].ob_spec)->te_ptext = numbuf;
  65.     strcpy((dmrkmsg[NEWBAD].ob_spec)->te_ptext, "0");  /* 0 new bad sector */
  66.     dmrkmsg[DMRKBAR].ob_width = 0;            /* haven't started yet */
  67.     dsplymsg(dmrkmsg);
  68.          
  69.     totbad = 0;    /* no NEW bad sectors yet */        
  70.     /* Loop for given number of passes */
  71.     while (pass) {
  72.         if ((ret = markdev(pdev, hdsiz, inbuf, pattern)) < 0) {
  73.             ret == ERROR;
  74.     } else {
  75.         totbad += ret;
  76.     }
  77.         pass--;
  78.     }
  79. wrapup:
  80.     erasemsg();
  81.     Mfree((long)inbuf);
  82.     if (ret < 0)
  83.         return (ret);
  84.     return(totbad);
  85. }
  86.  
  87.  
  88. /*
  89.  *  Fill up a character buffer with the given pattern.
  90.  *    Input:
  91.  *        buf - buffer to be filled.
  92.  *        size - size of buffer in bytes.
  93.  *        pattern - a 1-byte data to fill the buffer.
  94.  *    Output:
  95.  *        buf - buffer filled with the given pattern.
  96.  */
  97. fillbuf(buf, size, pattern)
  98. char *buf;
  99. long size;
  100. long pattern;
  101. {
  102.     long i;    /* index */
  103.     
  104.     for (i = 0; i < size; i += 4)
  105.     *(long *)&buf[i] = pattern;
  106. }
  107.  
  108.  
  109. /*
  110.  *  Markdev - Find bad sectors on a hard disk and record them in the Bad
  111.  *          Sector List.
  112.  *    Mechanism:
  113.  *        - write some given data to the entire device cylinder by
  114.  *          cylinder.
  115.  *        - read from the device cylinder by cylinder but in reverse
  116.  *          order.
  117.  *        - as data are read from the device, compare the written data
  118.  *          with the data read.  
  119.  *        - if there is any write, read or data error in a sector, that
  120.  *          sector will be considered bad.  (data error means data read
  121.  *          is different from data written.)
  122.  *        - add the bad sectors to the bad sector list.
  123.  *    Input:
  124.  *        pdev - physical device number.
  125.  *        hdsiz - size of hard disk in sectors.
  126.  *        databuf - buffer with the testing data.
  127.  *        pattern - data pattern to test with.
  128.  *    Output:
  129.  *        bsl - an updated bad sector list (ie. with newly found bad
  130.  *              sectors added to it).
  131.  *    Return:
  132.  *        totbad - total number of bad sectors found.
  133.  *        ERROR - Any of first 3 sectors on disk is bad.
  134.  */
  135. long
  136. markdev(pdev, hdsiz, databuf, pattern)
  137. int pdev;    /* phys dev number */
  138. long hdsiz;    /* size of hard disk in sectors */
  139. char *databuf;    /* testing data */ 
  140. long pattern;    /* data pattern */
  141. {
  142.     long sectcnt, cnt;        /* number of sectors to read */
  143.     long sect2mark;        /* number of sectors to mark */
  144.     SECTOR start, where;    /* where to start writing or reading */
  145.     long totbad;        /* total bad sectors found */
  146.     int nbad;            /* num bad sectors so far */
  147.     int ret=0;            /* return code from routines */
  148.     int clean;            /* indicate if chunk has any bad sector */
  149.     char numbuf[10];        /* buf to hold string converted from a number */
  150.  
  151.     
  152.     /*------------------------------------------------------------*/
  153.     /*  Write lots of sectors (MAXSECTS worth) at a time.      */
  154.     /*  If write error, loop through sectors within that cylinder */
  155.     /*  to find out exactly which sector(s) is bad, and add it to */
  156.     /*  the bad sector list if it's not already there.          */
  157.     /*------------------------------------------------------------*/
  158.  
  159.     sect2mark = hdsiz;        /* mark entire disk */
  160.     totbad = 0L;        /* no bad sectors yet */
  161.     nbad = 0;            /* no bad sectors found yet */
  162.     
  163.     start = 0L;
  164.     while (sect2mark != 0) {
  165.         if (sect2mark > MAXSECTS)
  166.             sectcnt = MAXSECTS;
  167.         else
  168.             sectcnt = sect2mark;
  169.             
  170.         /* fill buffer with given pattern */
  171.         fillbuf(databuf, (sectcnt << 9), pattern);
  172.             
  173.         if ((ret = wrsects(pdev, (int)sectcnt, databuf, start)) != 0) {
  174.             if (tsterr(ret) == OK) {
  175.                 ret = ERROR;
  176.                 goto badnews;
  177.             }
  178.             cnt = sectcnt;
  179.             where = start;
  180.             while (cnt) {
  181.                 if ((ret = wrsects(pdev, 1, databuf, where)) != 0) {
  182.             if (tsterr(ret) == OK) {
  183.             ret = ERROR;
  184.             goto badnews;
  185.             }
  186.                   if (where < 3) {
  187.                       ret = err(rsrvbad);
  188.                       goto badnews;
  189.                   }
  190.                     
  191.                      badbuf[nbad++] = where;    /* store bad sector num */
  192.                     
  193.                     /* buffer is filled up, have to add bad sectors
  194.                        found so far to the BSL before continuing.   */
  195.                     if (nbad == WARNBADSECTS) {
  196.                         if ((ret=addbsl(pdev, VENDOR, nbad)) < 0) {
  197.                             ret = ERROR;
  198.                             goto badnews;
  199.                         }
  200.                         totbad += ret;    /* increment num bad sectors existing */
  201.             prnbad(totbad);
  202.                         nbad = 0;    /* start counting again */
  203.                     }
  204.                 }
  205.                 where++;
  206.                 cnt--;
  207.             }
  208.         }
  209.  
  210.     if (nbad) {    /* there are bad sectors found not added to BSL yet */
  211.         if ((ret = addbsl(pdev, VENDOR, nbad)) < 0) {
  212.         ret = ERROR;
  213.         goto badnews; 
  214.         }
  215.         totbad += ret;    /* increment num bad sectors existing */
  216.         prnbad(totbad);
  217.     }
  218.     
  219.         /*-----------------------------------------------------------*/
  220.         /* Read lots of sectors (one cylinder worth) at a time.      */
  221.         /* If read error, loop through sectors within that cylinder  */
  222.         /* to find out exactly which sector(s) is bad, and add it to */
  223.         /* the bad sector list if it's not already there.         */
  224.         /*                                 */
  225.         /* Data read is compared to data written.  If there is any   */
  226.         /* discrepancy within a sector, mark that sector as bad in   */
  227.         /* the bad sector list.                         */
  228.         /*-----------------------------------------------------------*/
  229.  
  230.         nbad = 0;    /* no bad sectors for this cylinder yet */
  231.         if ((ret = rdsects(pdev, (int)sectcnt, databuf, start)) != 0) {
  232.             if (tsterr(ret) == OK) {
  233.                 ret = ERROR;
  234.                 goto badnews;
  235.             }
  236.             cnt = sectcnt;
  237.             where = start;
  238.             while (cnt) {
  239.                 if ((ret = rdsects(pdev, 1, databuf, where)) != 0) {
  240.                     if (tsterr(ret) == OK) {
  241.                     ret = ERROR;
  242.                     goto badnews;
  243.                     }
  244.                     if (where < 3) {
  245.                       ret = err(rsrvbad);
  246.                       goto badnews;
  247.                   }
  248.                      badbuf[nbad++] = where;    /* store bad sector num */
  249.                 } else {
  250.                     if (!blktst(databuf, pattern, 512L)) {
  251.                         if (where < 3) {
  252.                           ret = err(rsrvbad);
  253.                           goto badnews;
  254.                       }
  255.                         badbuf[nbad++] = where;    /* store bad sector num */
  256.                     }
  257.                 }
  258.         /* buffer is filled up, have to add bad sectors
  259.                    found so far to the BSL before continuing.   */
  260.                 if (nbad == WARNBADSECTS) {
  261.                     if ((ret=addbsl(pdev, VENDOR, nbad)) < 0) {
  262.                         ret = ERROR;
  263.                         goto badnews;
  264.                     }
  265.                     totbad += ret;    /* incr num bad sectors existing */
  266.                     prnbad(totbad);
  267.                     nbad = 0;    /* start counting again */
  268.                 }
  269.                 where++;
  270.                 cnt--;
  271.             }
  272.             clean = 0;
  273.         } else {
  274.             clean = 1;
  275.         }
  276.         
  277.         if (nbad) { /* there are bad sectors found not added to BSL yet */
  278.             if ((ret = addbsl(pdev, VENDOR, nbad)) < 0) {
  279.                 ret = ERROR;
  280.                 goto badnews;
  281.             }
  282.             totbad += ret;    /* incr num bad sectors added to BSL */
  283.             prnbad(totbad);
  284.         } else if (clean) {
  285.         /* compare data read with data written, record bad sectors if any */
  286.             if ((ret = cmpdata(pdev, start, databuf, (int)sectcnt, pattern))
  287.                  < 0) {
  288.                 ret = ERROR;
  289.                 goto badnews;
  290.             } else {
  291.                 totbad += ret;    /* incr num bad sectors added to BSL */
  292.                 prnbad(totbad);
  293.             }
  294.         }
  295.         start += sectcnt;
  296.         sect2mark -= sectcnt;
  297.         
  298.         /* update bar on screen */
  299.         dmrkmsg[DMRKBAR].ob_width
  300.             = (dmrkmsg[DMRKBOX].ob_width * (hdsiz - sect2mark)) / hdsiz;
  301.     objc_draw(dmrkmsg, DMRKBAR, MAX_DEPTH, 0, 0, wdesk, hdesk);
  302.     }
  303. badnews:
  304.     if (ret < 0)        /* if an error occurs,            */
  305.         return(ret);        /*    return the error            */
  306.     else return(totbad);    /* else return number of bad sectors found. */
  307. }
  308.  
  309.  
  310. /*
  311.  *  Update number of bad sectors found during Destructive Markbad in
  312.  *  the dialogue box.
  313.  *    Input:
  314.  *        totbad - number of bad sectors found so far.
  315.  */
  316. prnbad(totbad)
  317. long totbad;
  318. {
  319.     char numbuf[10];
  320.     
  321.     ltoa(totbad, numbuf);
  322.     (dmrkmsg[NEWBAD].ob_spec)->te_ptext = numbuf;
  323.     objc_draw(dmrkmsg, NEWBAD, MAX_DEPTH, 0, 0, wdesk, hdesk);
  324. }
  325.  
  326. /*
  327.  *  Compare data read with data written of a cylinder, and mark sectors
  328.  *  with data error in the bad sector list.
  329.  *    Input:
  330.  *        pdev - physical unit BSL belongs to.
  331.  *        start - starting physical sector number of the cylinder.
  332.  *        databuf - data read from the cylinder.
  333.  *        numsect - number of sectors to be compared.
  334.  *        pattern - long pattern written on the cylinder.
  335.  *    Output:
  336.  *        bsl - an updated bad sector list with the newly found bad
  337.  *              sectors marked in it.
  338.  */
  339. cmpdata(pdev, start, readbuf, numsect, pattern)
  340. int pdev;    /* physical device number */
  341. SECTOR start;    /* phys sect num of where cylinder starts */
  342. BYTE *readbuf;    /* data read */
  343. int numsect;    /* num sectors to be compared */
  344. long pattern;    /* correct data pattern */
  345. {
  346.     int i, cnt;            /* indices into databuf, counter */
  347.     int nbad;            /* num bad sectors found so far */
  348.     int totbad;            /* total num bad sectors found in cylinder */
  349.     int ret;            /* return code from addbsl() */
  350.     
  351.     totbad = nbad = 0;    /* no bad sectors found yet */
  352.     
  353.     /* Test whole chunk first, if OK, ship it.  
  354.        Return 0 for no bad sectors found. */
  355.     if (blktst(readbuf, pattern, (long)numsect*512))
  356.         return 0;
  357.         
  358.     for (cnt = 0; cnt < numsect; cnt++) {
  359.         if (!blktst(readbuf, pattern, 512L)) {
  360.         badbuf[nbad++] = start + cnt;    /* store bad sector num */
  361.     }
  362.     readbuf += 512L;
  363.         if (nbad == WARNBADSECTS) {
  364.             if ((ret = addbsl(pdev, VENDOR, nbad)) < 0) {
  365.                 return ret;
  366.             }
  367.             totbad += ret;    /* incr num bad sectors added to BSL */
  368.             nbad = 0;        /* reinit counter for bad sectors to 0 */
  369.         }
  370.     }
  371.     if (nbad) {    /* bad sectors found but not added to BSL yet */
  372.         if ((ret = addbsl(pdev, VENDOR, nbad)) < 0) {
  373.             return ret;
  374.         }
  375.         totbad += ret;    /* incr num bad sectors added to BSL */
  376.     }
  377.     return(totbad);
  378. }
  379.